FastAPI veakäitlus: kohandatud erandkäitlejad. Looge tugevaid API-sid elegantsete veateadetega parema kasutuskogemuse, töökindluse ja hooldatavuse eest.
Python FastAPI veakäitlus: Tugevate kohandatud erandkäitlejate loomine
Veakäitlus on tugevate ja töökindlate API-de loomisel ülioluline aspekt. Pythoni FastAPI-s saate kasutada kohandatud erandikäitlejaid, et vigu elegantselt hallata ja klientidele informatiivseid vastuseid pakkuda. See blogipostitus juhendab teid FastAPI-s kohandatud erandikäitlejate loomise protsessis, võimaldades teil luua vastupidavamaid ja kasutajasõbralikumaid rakendusi.
Miks kohandatud erandikäitlejad?
FastAPI pakub sisseehitatud tuge erandite käitlemiseks. Kuid ainult vaikimisi veavastustele tuginemine võib jätta kliendid ebamäärase või ebaefektiivse teabega. Kohandatud erandikäitlejad pakuvad mitmeid eeliseid:
- Parem kasutajakogemus: Pakkuge selgeid ja informatiivseid veateateid, mis on kohandatud konkreetsetele veaolukordadele.
- Tsentraliseeritud veahaldus: Koondage veakäitluse loogika ühte kohta, muutes oma koodi hooldatavamaks.
- Järjepidevad veavastused: Veenduge, et veavastused järgivad järjepidevat vormingut, parandades API kasutatavust.
- Täiustatud turvalisus: Vältige tundliku teabe avalikustamist veateadetes.
- Kohandatud logimine: Logige üksikasjalik veateave silumiseks ja jälgimiseks.
FastAPI erandikäitluse mõistmine
FastAPI kasutab vigade haldamiseks kombinatsiooni Pythoni sisseehitatud erandikäitluse mehhanismidest ja oma sõltuvuse süstimise süsteemist. Kui marsruudis või sõltuvuses tekib erand, otsib FastAPI selle töötlemiseks sobiva erandikäitleja.
Erandikäitlejad on funktsioonid, mis on kaunistatud @app.exception_handler()-ga ja mis võtavad kaks argumenti: erandi tüübi ja päringu objekti. Käitleja vastutab sobiva HTTP vastuse tagastamise eest.
Kohandatud erandite loomine
Enne kohandatud erandikäitlejate defineerimist on sageli kasulik luua kohandatud erandiklasse, mis esindavad teie rakenduses konkreetseid veaolukordi. See parandab koodi loetavust ja muudab eri tüüpi vigade käitlemise lihtsamaks.
Näiteks kui loote e-kaubanduse API-t ja peate käitlema olukordi, kus toode on laost otsas. Saate defineerida kohandatud erandiklassi nimega OutOfStockError:
class OutOfStockError(Exception):
def __init__(self, product_id: int):
self.product_id = product_id
self.message = f"Product with ID {product_id} is out of stock."
See kohandatud erandiklass pärib baasklassist Exception ja sisaldab product_id atribuuti ning kohandatud veateadet.
Kohandatud erandikäitlejate rakendamine
Nüüd loome kohandatud erandikäitleja OutOfStockError jaoks. See käitleja püüab erandi ja tagastab HTTP 400 (Bad Request) vastuse koos veateatega JSON-kerega.
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse
app = FastAPI()
class OutOfStockError(Exception):
def __init__(self, product_id: int):
self.product_id = product_id
self.message = f"Product with ID {product_id} is out of stock."
@app.exception_handler(OutOfStockError)
async def out_of_stock_exception_handler(request: Request, exc: OutOfStockError):
return JSONResponse(
status_code=400,
content={"message": exc.message},
)
@app.get("/products/{product_id}")
async def get_product(product_id: int):
# Simulate checking product stock
if product_id == 123:
raise OutOfStockError(product_id=product_id)
return {"product_id": product_id, "name": "Example Product", "price": 29.99}
Selles näites registreerib dekoraator @app.exception_handler(OutOfStockError) funktsiooni out_of_stock_exception_handler, et käidelda OutOfStockError erandeid. Kui OutOfStockError tekib get_product marsruudis, kutsutakse välja erandikäitleja. Käitleja tagastab seejärel JSONResponse'i olekukoodiga 400 ja veateadet sisaldava JSON-kerega.
Mitu eranditüüpi käitlemine
Saate defineerida mitu erandikäitlejat, et käidelda erinevaid eranditüüpe. Näiteks võite soovida käidelda ValueError erandeid, mis tekivad kasutaja sisendi parsimisel.
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
app = FastAPI()
@app.exception_handler(ValueError)
async def value_error_exception_handler(request: Request, exc: ValueError):
return JSONResponse(
status_code=400,
content={"message": str(exc)},
)
@app.get("/items/{item_id}")
async def get_item(item_id: int):
# Simulate invalid item_id
if item_id < 0:
raise ValueError("Item ID must be a positive integer.")
return {"item_id": item_id, "name": "Example Item"}
Selles näites käitleb funktsioon value_error_exception_handler ValueError erandeid. See eraldab veateate erandi objektist ja tagastab selle JSON-vastuses.
HTTPException kasutamine
FastAPI pakub sisseehitatud erandiklassi nimega HTTPException, mida saab kasutada HTTP-spetsiifiliste vigade tekitamiseks. See võib olla kasulik tavaliste veaolukordade, näiteks volitamata juurdepääsu või ressursside mittelaidmise käitlemiseks.
from fastapi import FastAPI, HTTPException
app = FastAPI()
@app.get("/users/{user_id}")
async def get_user(user_id: int):
# Simulate user not found
if user_id == 999:
raise HTTPException(status_code=404, detail="User not found")
return {"user_id": user_id, "name": "Example User"}
Selles näites tekitatakse HTTPException olekukoodiga 404 (Not Found) ja üksikasjaliku sõnumiga. FastAPI käitleb HTTPException erandeid automaatselt ja tagastab JSON-vastuse koos määratud olekukoodi ja üksikasjaliku sõnumiga.
Globaalsed erandikäitlejad
Samuti saate defineerida globaalsed erandikäitlejad, mis püüavad kõik käitlemata erandid. See võib olla kasulik vigade logimiseks või kliendile üldise veateate tagastamiseks.
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
import logging
app = FastAPI()
logger = logging.getLogger(__name__)
@app.exception_handler(Exception)
async def global_exception_handler(request: Request, exc: Exception):
logger.exception(f"Unhandled exception: {exc}")
return JSONResponse(
status_code=500,
content={"message": "Internal server error"},
)
@app.get("/error")
async def trigger_error():
raise ValueError("This is a test error.")
Selles näites käitleb funktsioon global_exception_handler kõiki erandeid, mida teised erandikäitlejad ei käitle. See logib vea ja tagastab 500 (Internal Server Error) vastuse koos üldise veateatega.
Vahevara kasutamine erandite käitlemiseks
Teine lähenemine erandite käitlemisele on vahevara (middleware) kasutamine. Vahevara funktsioonid täidetakse enne ja pärast iga päringut, võimaldades teil erandeid kõrgemal tasemel kinni püüda ja käidelda. See võib olla kasulik näiteks päringute ja vastuste logimiseks või kohandatud autentimise või autoriseerimise loogika rakendamiseks.
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
import logging
app = FastAPI()
logger = logging.getLogger(__name__)
@app.middleware("http")
async def exception_middleware(request: Request, call_next):
try:
response = await call_next(request)
except Exception as exc:
logger.exception(f"Unhandled exception: {exc}")
return JSONResponse(
status_code=500,
content={"message": "Internal server error"},
)
return response
@app.get("/error")
async def trigger_error():
raise ValueError("This is a test error.")
Selles näites mähkub funktsioon exception_middleware päringutöötlusloogika try...except plokki. Kui päringu töötlemise ajal tekib erand, logib vahevara vea ja tagastab 500 (Internal Server Error) vastuse.
Näide: rahvusvahelistamine (i18n) ja veateated
Globaalsele publikule API-sid luues kaaluge veateadete rahvusvahelistamist. See hõlmab veateadete pakkumist erinevates keeltes vastavalt kasutaja lokaadile. Kuigi täieliku i18n juurutamine jääb väljapoole käesoleva artikli ulatust, on siin lihtsustatud näide kontseptsiooni demonstreerimiseks:
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import JSONResponse
from typing import Dict
app = FastAPI()
# Mock translation dictionary (replace with a real i18n library)
translations: Dict[str, Dict[str, str]] = {
"en": {
"product_not_found": "Product with ID {product_id} not found.",
"invalid_input": "Invalid input: {error_message}",
},
"fr": {
"product_not_found": "Produit avec l'ID {product_id} introuvable.",
"invalid_input": "Entrée invalide\u00A0: {error_message}",
},
"es": {
"product_not_found": "Producto con ID {product_id} no encontrado.",
"invalid_input": "Entrada inválida: {error_message}",
},
"de": {
"product_not_found": "Produkt mit ID {product_id} nicht gefunden.",
"invalid_input": "Ungültige Eingabe: {error_message}",
}
}
def get_translation(locale: str, key: str, **kwargs) -> str:
"""Retrieves a translation for a given locale and key.
If the locale or key is not found, returns a default message.
"""
if locale in translations and key in translations[locale]:
return translations[locale][key].format(**kwargs)
return f"Translation missing for key '{key}' in locale '{locale}'."
@app.get("/products/{product_id}")
async def get_product(request: Request, product_id: int, locale: str = "en"):
# Simulate product lookup
if product_id > 100:
message = get_translation(locale, "product_not_found", product_id=product_id)
raise HTTPException(status_code=404, detail=message)
if product_id < 0:
message = get_translation(locale, "invalid_input", error_message="Product ID must be positive")
raise HTTPException(status_code=400, detail=message)
return {"product_id": product_id, "name": "Example Product"}
Peamised täiustused i18n näites:
- Lokaadi parameeter: Marsruut aktsepteerib nüüd
localepäringuparameetrit, mis võimaldab klientidel määrata oma eelistatud keele (vaikimisi "en" inglise keele jaoks). - Tõlkesõnastik:
translationssõnastik (näidis) salvestab veateated erinevate lokaatide jaoks (antud juhul inglise, prantsuse, hispaania, saksa). Reaalses rakenduses kasutaksite spetsiaalset i18n-teeki. get_translationfunktsioon: See abifunktsioon leiab sobiva tõlkelocalejakeyalusel. See toetab ka stringide vormindamist dünaamiliste väärtuste (naguproduct_id) sisestamiseks.- Dünaamilised veateated:
HTTPExceptiontõstetakse nüüddetailsõnumiga, mis genereeritakse dünaamiliselt funktsiooniget_translationabil.
Kui klient küsib /products/101?locale=fr, saab ta veateate prantsuse keeles (kui tõlge on saadaval). Kui küsitakse /products/-1?locale=es, saab ta Hispaania keeles veateate negatiivse ID kohta (kui see on saadaval).
Kui küsitakse /products/200?locale=xx (lokaat, millel tõlkeid pole), saadakse teade `Translation missing`.
Veakäitluse parimad tavad
Siin on mõned parimad tavad, mida FastAPI-s veakäitlust rakendades meeles pidada:
- Kasutage kohandatud erandeid: Defineerige kohandatud erandiklasse, mis esindavad teie rakenduses konkreetseid veaolukordi.
- Esitage informatiivseid veateateid: Lisage selged ja lühikesed veateated, mis aitavad klientidel vea põhjust mõista.
- Kasutage sobivaid HTTP olekukoode: Tagastage HTTP olekukoodid, mis kajastavad täpselt vea olemust. Näiteks kasutage 400 (Bad Request) sobimatu sisendi korral, 404 (Not Found) puuduvate ressursside korral ja 500 (Internal Server Error) ootamatute vigade korral.
- Vältige tundliku teabe avaldamist: Olge ettevaatlik, et te ei avaldaks veateadetes tundlikku teavet, nagu andmebaasi mandaadid või API võtmed.
- Logige vead: Logige üksikasjalik veateave silumiseks ja jälgimiseks. Kasutage logimise teeki, näiteks Pythoni sisseehitatud
loggingmoodulit. - Tsentraliseerige veakäitluse loogika: Koondage veakäitluse loogika ühte kohta, näiteks kohandatud erandikäitlejatesse või vahevarasse.
- Testige oma veakäitlust: Kirjutage ühiktestid, et tagada veakäitluse loogika korrektne toimimine.
- Kaaluge spetsiaalse veajälgimisteenuse kasutamist: Tootmiskeskkondade jaoks kaaluge spetsiaalsete veajälgimisteenuste (nt Sentry või Rollbar) kasutamist vigade jälgimiseks ja analüüsimiseks. Need tööriistad pakuvad väärtuslikku teavet teie rakenduse seisundi kohta ja aitavad teil probleeme kiiresti tuvastada ja lahendada.
Kokkuvõte
Kohandatud erandikäitlejad on võimas tööriist tugevate ja kasutajasõbralike API-de loomiseks FastAPI-s. Kohandatud erandiklasse ja käitlejaid defineerides saate vigu elegantselt hallata, pakkuda klientidele informatiivseid vastuseid ning parandada oma rakenduse üldist töökindlust ja hooldatavust. Kohandatud erandite, HTTPException-ide ja i18n-põhimõtete rakendamine, kui see on asjakohane, aitab teie API-l saavutada globaalset edu.
Pidage meeles, et veakäitluse strateegia kujundamisel arvestage kasutajakogemusega. Esitage selged ja lühikesed veateated, mis aitavad kasutajatel probleemi ja selle lahendamise viisi mõista. Tõhus veakäitlus on kvaliteetsete API-de loomise nurgakivi, mis vastavad mitmekesise globaalse publiku vajadustele.